package com.ultrapower.util;

public class CommonUtils {
	public static long reverseTimeMillis(long currentTimeMillis) {
		return Long.MAX_VALUE - currentTimeMillis;
	}

	public static long reverseCurrentTimeMillis() {
		return reverseTimeMillis(System.currentTimeMillis());
	}

	public static long recoveryTimeMillis(long reverseCurrentTimeMillis) {
		return Long.MAX_VALUE - reverseCurrentTimeMillis;
	}

	public static int fastAbs(final int value) {
		return value & Integer.MAX_VALUE;
	}

	public static boolean stringEquals(final CharSequence cs1, final CharSequence cs2) {
		if (cs1 == cs2) {
			return true;
		}
		if (cs1 == null || cs2 == null) {
			return false;
		}
		if (cs1.length() != cs2.length()) {
			return false;
		}
		if (cs1 instanceof String && cs2 instanceof String) {
			return cs1.equals(cs2);
		}
		return regionMatches(cs1, false, 0, cs2, 0, cs1.length());
	}

	static boolean regionMatches(final CharSequence cs, final boolean ignoreCase, final int thisStart,
			final CharSequence substring, final int start, final int length) {
		if (cs instanceof String && substring instanceof String) {
			return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length);
		}
		int index1 = thisStart;
		int index2 = start;
		int tmpLen = length;

		// Extract these first so we detect NPEs the same as the
		// java.lang.String version
		final int srcLen = cs.length() - thisStart;
		final int otherLen = substring.length() - start;

		// Check for invalid parameters
		if (thisStart < 0 || start < 0 || length < 0) {
			return false;
		}

		// Check that the regions are long enough
		if (srcLen < length || otherLen < length) {
			return false;
		}

		while (tmpLen-- > 0) {
			final char c1 = cs.charAt(index1++);
			final char c2 = substring.charAt(index2++);

			if (c1 == c2) {
				continue;
			}

			if (!ignoreCase) {
				return false;
			}

			// The same check as in String.regionMatches():
			if (Character.toUpperCase(c1) != Character.toUpperCase(c2)
					&& Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
				return false;
			}
		}

		return true;
	}

	public static long roundToNearestMultipleOf(final long num, final long multipleOf) {
		if (num < 0) {
			throw new IllegalArgumentException("num cannot be negative");
		}
		if (multipleOf < 1) {
			throw new IllegalArgumentException("cannot round to nearest multiple of values less than 1");
		}
		if (num < multipleOf) {
			return multipleOf;
		}
		if ((num % multipleOf) >= (multipleOf / 2.0)) {
			return (num + multipleOf) - (num % multipleOf);
		} else {
			return num - (num % multipleOf);
		}
	}
}
